package website.haicheng.server.config;

import cn.hutool.extra.spring.SpringUtil;
import org.springframework.stereotype.Component;
import website.haicheng.server.common.annotations.Handler;
import website.haicheng.server.common.enums.MessageEnum;
import website.haicheng.server.handlers.MessageHandler;
import website.haicheng.server.handlers.ServerHandler;
import website.haicheng.server.model.Message;
import io.netty.channel.Channel;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @Author: 582895699@qq.com
 * @Desctription: Netty初始化
 * @Date: Created in 2021/12/3 10:30
 */
@Component
public class NettyRunner implements InitializingBean, MessageHandler {

    Map<MessageEnum, MessageHandler> messageEnumMessageHandlerMap = new HashMap<>();

    /**
     * 初始化{@link ServerHandler}
     *
     * @return ServerHandler
     */
    @Bean
    public ServerHandler serverHandler() {
        return new ServerHandler(this);
    }

    /**
     * 启动时加载逻辑处理映射关系
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        Map<String, MessageHandler> beansOfType = SpringUtil.getBeansOfType(MessageHandler.class);
        Set<Map.Entry<String, MessageHandler>> entries = beansOfType.entrySet();
        for (Map.Entry<String, MessageHandler> entry : entries) {
            MessageHandler messageHandler = entry.getValue();
            Handler annotation = messageHandler.getClass().getAnnotation(Handler.class);
            if (Objects.isNull(annotation)) {
                continue;
            }
            messageEnumMessageHandlerMap.put(annotation.value(), messageHandler);
        }
    }

    /**
     * 逻辑处理
     *
     * @param channel Channel
     * @param message Message
     */
    @Override
    public void process(Channel channel, Message message) {
        MessageHandler messageHandler = messageEnumMessageHandlerMap.get(MessageEnum.valueOf(message.getType()));
        if (Objects.isNull(messageHandler)) {
            return;
        }
        messageHandler.process(channel, message);
    }
}
